package ferp.center.server.task;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.taskqueue.TaskHandle;
import ferp.center.server.Action;
import ferp.center.server.entity.Range;
import ferp.center.server.entity.Rating;
import ferp.center.server.ranking.Ranker;

import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static com.google.appengine.api.taskqueue.TaskOptions.Builder.withUrl;

/**
 * User: igorgok
 * Date: 6/6/13 12:24 PM
 */
public class TaskRangeTreeRemoveRating extends HttpServlet
{
  public static void queue(Rating rating)
  {
    Key leaf = rating.getRange();
    TaskHandle t = Ranker.queue(withUrl(URL).
                                param(RID, KeyFactory.keyToString(rating.getKey())).
                                param(CFG, rating.getConfiguration()).
                                param(VALUE, String.valueOf(rating.getValue())).
                                param(LEAF, leaf == null ? "" : KeyFactory.keyToString(leaf)));

    Action.logger().info("queued rating removal, key=[" + rating.getKey() + "], value=" + rating.getValue() + ", handle=" + t.toString());
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  {
    Action.execute(request, new Action.Task()
    {
      @Override
      protected void run(EntityManager em, HttpServletRequest request) throws IOException
      {
        String rid = request.getParameter(RID);
        String lid = request.getParameter(LEAF);
        Rating rating = em.find(Rating.class, KeyFactory.stringToKey(rid));
        Range leaf = (lid.isEmpty() ? null : em.find(Range.class, KeyFactory.stringToKey(lid)));

        if (rating != null)
        {
          rating.setRange(null);

          log("removed rating in configuration [" + request.getParameter(CFG) + "], value=" + request.getParameter(VALUE));
        }
        else
          log("could not find rating " + rid);

        if (leaf != null)
        {
          Ranker.remove(em, leaf);

          log(leaf.getSize() > 0 ? ("remaining attached ratings: " + leaf.getSize()) : "removed associated leaf range");
        }
        else
          log("could not find leaf " + lid);
      }
    });
  }

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  {
    throw new ServletException("GET method is not supported");
  }

  private static final String URL = Url.rt("remove/rating");
  private static final String RID = "rid";
  private static final String CFG = "cfg";
  private static final String VALUE = "value";
  private static final String LEAF = "leaf";
}
